home *** CD-ROM | disk | FTP | other *** search
/ Amiga Game-Power / Amiga Game-Power.iso / anwendungen / gw print / bcpl / myrun.c < prev    next >
C/C++ Source or Header  |  1994-05-20  |  8KB  |  225 lines

  1. /* Myrun.c - a C language replacement for RUN
  2. Compile and link with Manx 3.4:
  3.   cc myrun
  4.   ln myrun.o bcpllib.o -lc
  5. By Bill Kinnersley - Dec 18, 1987
  6. Mail:   Physics Dept.
  7.         Montana State University
  8.         Bozeman, MT 59717
  9. BITNET: iphwk@mtsunix1
  10. INTERNET: iphwk%mtsunix1.bitnet@cunyvm.cuny.edu
  11. UUCP: ...psuvax1!mtsunix1.bitnet!iphwk
  12. */
  13. #include <stdio.h>
  14. #include <libraries/dosextens.h>
  15. #include <functions.h>
  16. #include <exec/memory.h>
  17. #include "BCPL.h"
  18. #define DOSTRUE -1L
  19. struct pathlist {
  20.         BPTR next;
  21.         BPTR lock;
  22. };
  23. long cli_init();
  24. struct pathlist *copypath();
  25. long *gv;
  26. main() {
  27.         struct RootNode *root;
  28.         struct DosLibrary *doslib;
  29.         struct Task *mytask;
  30.         struct Process *myproc, *newproc;
  31.         struct CommandLineInterface *cli;
  32.         struct DosPacket *pkt;
  33.         struct FileLock *lock;
  34.         struct FileHandle *cis, *cos, *myfh;
  35.         char *oldbuf, *mybuf;
  36.         long clitask, *tskarr, taskno, end, size, *buf, i,
  37.                 stsz, sz, *mysegarray, *newsegarray, res, res2, pri;
  38.         BPTR cd=0, procname=0;
  39.         BCPLInit();
  40.         myproc = (struct Process *)FindTask(0L);
  41.         res2 = myproc->pr_Result2;
  42. /* Here's where RUN finds the command line when called by EXECUTE
  43.    Unfortunately, the Manx startup code overwrites Result2 */
  44.         res2 = 0;
  45.         cis = (struct FileHandle *)BADDR(myproc->pr_CIS);
  46.         cos = (struct FileHandle *)BADDR(myproc->pr_COS);
  47.         newproc = 0;
  48.         newsegarray = (long *)AllocMem(20L, MEMF_PUBLIC);*newsegarray++ = 20;
  49.         doslib = (struct DosLibrary *)OpenLibrary("dos.library", 0L);
  50.         root = (struct RootNode *)doslib->dl_Root;
  51.         tskarr = (long *)BADDR(root->rn_TaskArray);
  52.         taskno = 0;
  53.         mytask = &myproc->pr_Task;
  54.         pri = mytask->tc_Node.ln_Pri;
  55.         mysegarray = (long *)BADDR(myproc->pr_SegList);
  56.         gv = (long *)myproc->pr_GlobVec;
  57.         cli = (struct CommandLineInterface *)BADDR(myproc->pr_CLI);
  58.         if (res2) {     /* called by EXECUTE */
  59.                 oldbuf = (char *)BADDR(res2);
  60.                 end = *oldbuf++;
  61.         }
  62.         else {
  63.                 end = cis->fh_End;
  64.                 oldbuf = (char *)BADDR(cis->fh_Buf);
  65.         }
  66.         size = 4L*(end/4L + 13L);
  67. printf("end=%ld oldbuf=%lx bufsize=%ld\n", end, oldbuf, size);
  68.         buf = (long *)AllocMem(size, MEMF_CLEAR); *buf++ = size;
  69.         myfh = (struct FileHandle *)buf;
  70.         mybuf = (char *)((long)myfh + 44L);
  71.         for (i=0; i<end; i++) mybuf[i] = oldbuf[i];
  72.         mybuf[end] = '\n';
  73. for (i=0; i<=end; i++) printf("%c",mybuf[i]);
  74.         newsegarray[0] = 4;
  75.         newsegarray[1] = mysegarray[1];
  76.         newsegarray[2] = mysegarray[2];
  77.         newsegarray[3] = 0;
  78.         newsegarray[4] = (long)root->rn_ConsoleSegment;
  79. printf("copied segarray %ld %lx %lx %lx %lx\n",newsegarray[0],newsegarray[1],
  80. newsegarray[2],newsegarray[3],newsegarray[4]);
  81.         procname = MakeBSTR("Background CLI");
  82.         stsz = 3200;
  83.         Forbid();
  84.         sz = tskarr[0];
  85.         for (taskno=1; taskno<=sz; taskno++) if (!tskarr[taskno]) break;
  86.         if (!(clitask = BCPL(CREATEPROCB, bptr(newsegarray), stsz>>2, pri,
  87.                 procname, bptr(gv)))) {
  88.                 if (taskno) tskarr[taskno] = 0;
  89.                 Permit();
  90.                 if (!res2) printf("RUN failed\n");
  91.                 FreeMem(newsegarray, 20L);
  92.                 FreeMem(myfh, size);
  93.                 FreeBSTR(procname);
  94.                 BCPLQuit();
  95.                 exit(20);
  96.         }
  97. printf("clitask=%lx\n",clitask);
  98.         tskarr[taskno] = (long)clitask;
  99.         newproc =(struct Process *)((long)clitask-(long)sizeof(struct Task));
  100.         newproc->pr_TaskNum = taskno;
  101.         Permit();
  102.         myfh->fh_Buf = (long)bptr(mybuf);
  103.         myfh->fh_End = end + 1L;
  104.         cd = cli ? DupLock(myproc->pr_CurrentDir) : 0;
  105. printf("ready to dospacket\n");
  106.         if (!BCPL(SENDPKT, DOSTRUE, clitask, cli_init, 0L, 0L, bptr(cli),
  107.                 bptr(cis), bptr(cos), bptr(myfh), cd, res2))
  108.                 printf("[CLI %ld]\n", taskno);
  109. printf("dospacketed\n");
  110.         FreeBSTR(procname);
  111.         BCPLQuit();
  112.         exit(0);
  113. }
  114. struct clistartup {
  115.         long unused[5];
  116.         BPTR cli, cis, cos, fh, cd;
  117.         long res2;
  118. };
  119. long retval;
  120. long cli_init(arg) BPTR arg; {
  121.         struct clistartup *pkt; /* this MUST be the FIRST local */
  122.         struct Process *mytask;
  123.         struct CommandLineInterface *oldcli, *mycli;
  124.         struct FileHandle *fh, *input;
  125.         BPTR output;
  126.         long max, i, putpkt, flag, flagset, *mysegarr, inisint, outisint;
  127.         char *prompt, *newprompt, *curdir, *newcurdir;
  128. #asm
  129.         movem.l a1/a3,-(a7)
  130.         asl.l   #2,d1
  131.         move.l  d1,-4(a5)       ;this initializes pkt */
  132. #endasm
  133.         geta4();
  134.         oldcli = (struct CommandLineInterface *)BADDR(pkt->cli);
  135.         fh = (struct FileHandle *)BADDR(pkt->fh);
  136.         mytask = (struct Process *)FindTask(0L);
  137.         mycli = (struct CommandLineInterface *)BADDR(mytask->pr_CLI);
  138.         flag = !(pkt->res2);
  139.         output = 0;
  140.         inisint = FALSE;
  141.         flagset = -4;
  142.         mycli->cli_CurrentInput = mycli->cli_StandardInput = pkt->fh;
  143.         if (!flag) {
  144.                 input = (struct FileHandle *)BADDR(pkt->cis);
  145.                 if (input) {
  146.                         mycli->cli_StandardInput = pkt->cis;
  147.                         mytask->pr_ConsoleTask = (APTR)input->fh_Type;
  148.                         inisint = (long)input->fh_Port;
  149.                         flagset |= 2;
  150.                 }
  151.                 output = pkt->cos;
  152.         }
  153.         if (!output) {
  154.                 flagset |= 1;
  155.                 output = Open("*", MODE_NEWFILE);
  156.         }
  157.         outisint = (long)((struct FileHandle *)BADDR(output))->fh_Port;
  158.         mycli->cli_Background = (outisint && inisint) ? 0 : DOSTRUE;
  159.         CurrentDir(pkt->cd);
  160.         init(mycli, output, oldcli);
  161.         mysegarr = (long *)BADDR(mytask->pr_SegList);
  162.         mysegarr[3] = 0;
  163.         retval = flag ? gv[42] /* putpkt */ : flagset;
  164. printf("FINISHED retval=%lx\n", retval);
  165.         mytask->pr_Result2 = bptr(pkt);
  166. #asm
  167.         dseg
  168.         public  _a0
  169.         cseg
  170.         lea     _retval,a1
  171.         move.l  (a1),d1
  172.         lea     _a0,a0
  173.         move.l  0(a0),a2
  174.         move.l  8(a0),a6
  175.         suba.l  a0,a0
  176.         movem.l (a7)+,a1/a3
  177.         unlk    a5
  178.         jmp     (a6)
  179. #endasm
  180. }
  181. init(cli, output, oldcli)
  182. struct CommandLineInterface *cli, *oldcli; BPTR output; {
  183.         long stsz, max, i;
  184.         BPTR path, b;
  185.         char *prompt, *curdir, *newprompt, *newcurdir, *bstr;
  186.         b = oldcli ? oldcli->cli_Prompt : MakeBSTR("%N>");
  187.         prompt = (char *)BADDR(b);
  188.         newprompt = (char *)BADDR(cli->cli_Prompt);
  189.         max = prompt[0];
  190.         for (i=0; i<=max; i++) newprompt[i] = prompt[i];
  191.         b = oldcli ? oldcli->cli_SetName : MakeBSTR("SYS:");
  192.         curdir = (char *)BADDR(b);
  193.         newcurdir = (char *)BADDR(cli->cli_SetName);
  194.         max = curdir[0];
  195.         for (i=0; i<=max; i++) newcurdir[i] = curdir[i];
  196.         bstr = (char *)BADDR(cli->cli_CommandFile);
  197.         bstr[0] = 0;
  198.         stsz = oldcli ? oldcli->cli_DefaultStack : 1000;
  199.         cli->cli_DefaultStack = stsz;
  200.         path = oldcli ? bptr(copypath(oldcli->cli_CommandDir)) : 0;
  201.         cli->cli_CommandDir = path;
  202.         cli->cli_StandardOutput = cli->cli_CurrentOutput = output;
  203.         cli->cli_FailLevel = 10;
  204. }
  205. struct pathlist *copypath(arg) BPTR arg; {
  206. /* The PATH is stored in cli_CommandDir as a linked list of Locks */
  207. /* Each newly created CLI must inherit the PATH of its creator */
  208.         struct pathlist *oldlist, *newlist, *link, *lastlink;
  209.         long *mem;
  210.         newlist = NULL;
  211.         lastlink = (struct pathlist *)&newlist;
  212.         oldlist = (struct pathlist *)BADDR(arg);
  213.         while (oldlist) {
  214.                 if (!(mem = (long *)AllocMem(12L, 1L))) break;
  215.                 mem[0] = 12L;
  216.                 link = (struct pathlist *)&mem[1];
  217.                 link->next = NULL;
  218.                 link->lock = DupLock(oldlist->lock);
  219.                 lastlink->next = bptr(link);
  220.                 lastlink = link;
  221.                 oldlist = (struct pathlist *)BADDR(oldlist->next);
  222.         }
  223.         return (struct pathlist *)(BADDR(newlist));
  224. }
  225.